package com.baor.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baor.dao.*;
import com.baor.domain.*;
import com.baor.domain.conf.DistributionConf;
import com.baor.domain.middle.Nouse;
import com.baor.domain.middle.RewardRuleMiddle;
import com.baor.service.AppletService;
import com.baor.utils.AjaxResult;
import com.baor.utils.DateUtil;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class AppletServiceImpl implements AppletService {

    @Autowired
    private VipDao vipDao;
    @Autowired
    private ProxyOrderDao proxyOrderDao;
    @Autowired
    private ProxyDao proxyDao;
    @Autowired
    private OrderDao orderDao;
    @Autowired
    private ExamineDao examineDao;
    @Autowired
    private DistributorDao distributorDao;
    @Autowired
    private DistributionConfDao distributionConfDao;
    @Autowired
    private CycleDao cycleDao;
    @Autowired
    private RewardDao rewardDao;
    @Autowired
    private RuleDao ruleDao;
    @Autowired
    private RewardRuleDao rewardRuleDao;



    @Override
    public AjaxResult<?> channelAgent(int userId) {
        Map<String, Object> res = new HashMap<>();
        UserVo user = vipDao.selectById(userId);
        res.put("image", user.getUserImage());
        res.put("phone", user.getUserTel());
        //判断是否为代理商
        ProxyVo proxy = proxyDao.selectOne(new LambdaQueryWrapper<ProxyVo>().eq(ProxyVo::getUserId, userId));
        if(proxy == null){
            res.put("msg","您还不是渠道代理商");
            return AjaxResult.error(res);
        }
        //已结算
        MPJLambdaWrapper<ProxyOrderVo> mpj = new MPJLambdaWrapper<>();
        mpj.selectAll(ProxyOrderVo.class)
                .eq(OrderVo::getOrderStatusId,"12")
                .leftJoin(OrderVo.class,OrderVo::getOrderId, ProxyOrderVo::getOrderId);
        List<ProxyOrderVo> proxyOrderVos = proxyOrderDao.selectList(mpj);
        BigDecimal settled = BigDecimal.ZERO;
        for (ProxyOrderVo proxyOrderVo : proxyOrderVos) {
            settled = settled.add(proxyOrderVo.getAllCommission());
        }
        res.put("settled", settled);
        //未结算
        MPJLambdaWrapper<ProxyOrderVo> mpj2 = new MPJLambdaWrapper<>();
        mpj2.selectAll(ProxyOrderVo.class)
                .ne(OrderVo::getOrderStatusId,"12")
                .leftJoin(OrderVo.class,OrderVo::getOrderId, ProxyOrderVo::getOrderId);
        List<ProxyOrderVo> proxyOrderVos2 = proxyOrderDao.selectList(mpj2);
        BigDecimal unSettled = BigDecimal.ZERO;
        for (ProxyOrderVo proxyOrderVo : proxyOrderVos2) {
            unSettled = unSettled.add(proxyOrderVo.getAllCommission());
        }
        res.put("unSettled", unSettled);
        return AjaxResult.success(res);
    }

    @Override
    public AjaxResult<?> examine(Map<String, Object> param) {
        ExamineVo examineVo = insert(param);
        if(examineVo == null)
            return AjaxResult.error("该用户已是分销商,或已在申请中");
        DistributionConf conf = distributionConfDao.selectOne(new LambdaQueryWrapper<DistributionConf>().eq(DistributionConf::getSiteId, examineVo.getSiteId()));
        if(conf.getConfMethod() == 2)
            return AjaxResult.error("该站点还未开启申请成为分销商功能");
        if(conf.getConfMethod() == 1){
            Map<String, Object> res= new HashMap<>();
            res.put("msg","该站点暂未开启申请功能");
            if(conf.getConfDistributionCondition() == 1){
                res.put("condition","成为分销商条件：消费100次以上");
            } else if (conf.getConfDistributionCondition() == 2) {
                res.put("condition","成为分销商条件：消费10000元以上");
            }else {
                res.put("condition","成为分销商条件：购买指定商品");
            }
            return AjaxResult.error(res);
        }
        if(conf.getConfMethod() == 0){
            int row = condition(conf,examineVo);
            if(row > 0)
                return AjaxResult.success();
            else
                return AjaxResult.error("没有达到申请条件");
        }
        return AjaxResult.error();
    }

    @Override
    public AjaxResult<?> reward(int userId) {
        Map<String, Object> res = new HashMap<>();
        //查出索引周期
        List<CycleVo> cycleList = cycleDao.selectList(null);
        //销售奖励
        BigDecimal reward = new BigDecimal(0);
        //待发放奖励
        BigDecimal unReward = BigDecimal.ZERO;
        all:for(CycleVo cycle : cycleList){
            //查看该周期是否开启奖励配置
            RewardVo rewardVo = rewardDao.selectOne(new LambdaQueryWrapper<RewardVo>().eq(RewardVo::getRewardConfId, cycle.getRewardConfId()));
            //奖励指标
            BigDecimal rewardLimit = rewardVo.getConfBasic();
            if(rewardVo.getConfStatus().equals("0")){
                continue;
            }
            //查出所有用户在该周期的奖励
            List<Nouse> list = rewardDao.sumReward(cycle);
            //过滤没有达到奖励指标的用户
            List<Nouse> filterList = list.stream().filter(nouse -> nouse.getGoodsValue().compareTo(rewardLimit) >= 0).collect(Collectors.toList());
            if(list.stream().map(Nouse::getUserId).collect(Collectors.toList()).contains(userId)) {
                //查出该周期的奖励规则
                List<RuleVo> ruleList = getRule(Integer.parseInt(cycle.getRewardConfId()));
                for (int i = 1; i <= list.size(); i++) {
                    if (list.get(i-1).getUserId().equals(userId)) {
                        if(ruleList.get(ruleList.size()-1).getRuleRange() < i){
                            continue all;
                        }
                        reward = reward.add(getReward(ruleList, i));
                        if(cycle.getGrantStatus().equals("0")) {
                            unReward = unReward.add(getReward(ruleList, i));
                            res.put("grantTime", cycle.getCycleEndTime());
                        }
                        break;
                    }
                }
            }
        }
        res.put("reward", reward);
        res.put("unReward", unReward);
        return AjaxResult.success(res);
    }

    @Override
    public AjaxResult<?> click(int userId) {
        DistributorVo distributor = distributorDao.selectOne(new LambdaQueryWrapper<DistributorVo>().eq(DistributorVo::getUserId, userId));
        if(distributor != null)
            return AjaxResult.error("该用户已是分销商");
        //查站点id
        int siteId = Integer.parseInt(vipDao.selectById(userId).getSiteId());
        //查看该站点分销设置
        DistributionConf conf = distributionConfDao.selectOne(new LambdaQueryWrapper<DistributionConf>().eq(DistributionConf::getSiteId, siteId));
        if(conf.getConfMethod() == 1){
            if(conf.getConfDistributionCondition() == 1){
                return AjaxResult.success("成为分销商条件：消费100次以上");
            } else if (conf.getConfDistributionCondition() == 2) {
                return AjaxResult.success("成为分销商条件：消费10000元以上");
            }else {
                return AjaxResult.success("成为分销商条件：购买指定商品");
            }
        }
        return AjaxResult.success();
    }

    @Override
    @Transactional
    public AjaxResult<?> registIf(int id) {
        int code = 0;
        //查出站点id
        UserVo user = vipDao.selectById(id);
        int siteId = Integer.parseInt(user.getSiteId());
        //查看该站点分销设置
        DistributionConf conf = distributionConfDao.selectOne(new LambdaQueryWrapper<DistributionConf>().eq(DistributionConf::getSiteId, siteId));
        if(conf.getConfMethod() == 1 && conf.getConfDistributionCondition() == 0){
            DistributorVo distributorVo = new DistributorVo();
            distributorVo.setUserId(String.valueOf(id));
            distributorVo.setSiteId(String.valueOf(siteId));
            distributorVo.setDistributionLevelId("2");
            distributorVo.setDistributorId(Integer.valueOf(user.getUserSuperior()));
            code = insertDis(distributorVo).getCode();
        }
        if(code == 200)
            return AjaxResult.success();
        else
            return AjaxResult.error();
    }

    @Override
    public AjaxResult<?> check(int id) {
        DistributorVo distributor = distributorDao.selectOne(new LambdaQueryWrapper<DistributorVo>().eq(DistributorVo::getUserId, id));
        if(distributor != null)
            return AjaxResult.success("该用户已是分销商");
        else
            return AjaxResult.error("该用户不是分销商");
    }

    @Override
    public AjaxResult<?> checkConf(int siteId) {
        DistributionConf conf = distributionConfDao.selectOne(new LambdaQueryWrapper<DistributionConf>().eq(DistributionConf::getSiteId, siteId));
        if(conf.getConfMethod() == 1){
            if(conf.getConfDistributionCondition() == 1){
                return AjaxResult.error("不能直接申请。成为分销商条件：消费100次以上");
            } else if (conf.getConfDistributionCondition() == 2) {
                return AjaxResult.error("不能直接申请。成为分销商条件：消费10000元以上");
            }else {
                return AjaxResult.error("不能直接申请。成为分销商条件：购买指定商品");
            }
        }
        if(conf.getConfMethod() == 2){
            return AjaxResult.error("该站点暂未开启申请功能");
        }
        return AjaxResult.success("可以正常申请成为分销商");
    }

    @Transactional
    public AjaxResult<?> insertDis(DistributorVo vo) {
        LambdaQueryWrapper<DistributorVo> lqw = new LambdaQueryWrapper<>();
        lqw.eq(DistributorVo::getUserId, vo.getUserId());
        List<DistributorVo> lists = distributorDao.selectList(lqw);
        if(lists.size() > 0){
            return AjaxResult.error("该用户已是分销商，请勿重复添加");
        }
        int userId = Integer.parseInt(distributorDao.selectById(vo.getDistributorId()).getUserId());
        UserVo user = new UserVo();
        user.setUserSuperior(userId+"");
        user.setUserId(Integer.valueOf(vo.getUserId()));
        vo.setDistributorId(null);
        vipDao.updateById(user);
        Boolean flag = true;
        while(flag){
            String code = "NO" + getNum();
            MPJLambdaWrapper<DistributorVo> mpj = new MPJLambdaWrapper<>();
            mpj.selectAll(DistributorVo.class)
                    .eq(DistributorVo::getDistributiorCode, code);
            List<DistributorVo> list = distributorDao.selectList(mpj);
            if(list.size() > 0){
                return AjaxResult.error("该编号已存在，请重新输入");
            }else {
                vo.setDistributiorCode(code);
                flag = false;
            }
        }
        vo.setCreateTime(DateUtil.now());
        int row = distributorDao.insert(vo);
        if (row > 0){
            return AjaxResult.success();
        }else {
            return AjaxResult.error();
        }
    }

    public static int getNum(){
        int min = 100000;
        int max = 999999;
        int num = (int)(Math.random() * ((max - min) + 1)) + min;
        return num;
    }

    public BigDecimal getReward(List<RuleVo> ruleList, int i) {
        BigDecimal reward = new BigDecimal(0);
        int count = 0;
        while(count < ruleList.size()){
            if(i <= ruleList.get(count).getRuleRange()){
                reward = reward.add(ruleList.get(count).getRuleMoney());
                break;
            }
            count++;
        }
        return reward;
    }

    public List<RuleVo> getRule(int rewardConfId){
        //查出该周期内所有奖励规则
        List<Integer> ruleIds = rewardRuleDao.selectList(new LambdaQueryWrapper<RewardRuleMiddle>()
                        .eq(RewardRuleMiddle::getRewardId, rewardConfId))
                .stream().map(RewardRuleMiddle::getRuleId).collect(Collectors.toList());
        List<RuleVo> list = ruleDao.selectList(new LambdaQueryWrapper<RuleVo>().in(RuleVo::getRuleId, ruleIds).orderByDesc(RuleVo::getRuleMoney));
        return list;
    }

    public ExamineVo insert(Map<String, Object> param){
        UserVo user = vipDao.selectById(Integer.valueOf(param.get("userId").toString()));
        DistributorVo distributor = distributorDao.selectOne(new LambdaQueryWrapper<DistributorVo>().eq(DistributorVo::getUserId, user.getUserId()));
        if(distributor != null)
            return null;
        ExamineVo examineVo = examineDao.selectOne(new LambdaQueryWrapper<ExamineVo>().eq(ExamineVo::getUserId, user.getUserId()));
        if (examineVo != null)
            return null;
        ExamineVo examine = new ExamineVo();
        examine.setSiteId(user.getSiteId());
        examine.setUserId(String.valueOf(user.getUserId()));
        examine.setUserName(user.getUserName());
        if(param.get("superior") != null && !"".equals(param.get("superior")) && Integer.parseInt(param.get("superior").toString()) > 0){
            examine.setSuperiorId(param.get("superior").toString());
        }
        //计算消费次数和金额
        LambdaQueryWrapper<OrderVo> lqw = new LambdaQueryWrapper<>();
        lqw.eq(OrderVo::getOrderStatusId, "12")
                .eq(OrderVo::getUserId, user.getUserId());
        List<OrderVo> orderVos = orderDao.selectList(lqw);
        BigDecimal cost = new BigDecimal(0);
        for(OrderVo orderVo : orderVos){
            cost = cost.add(orderVo.getOrderRealAmount());
        }
        examine.setCost(cost);
        examine.setCostNum(orderVos.size());
        examine.setCreateTime(DateUtil.now());
        examine.setAdminId(String.valueOf(examineDao.selectAdminId(Integer.parseInt(user.getSiteId()))));
        return examine;
    }

    public int condition(DistributionConf conf,ExamineVo examineVo){
        int row = 0;
        if(conf.getConfDistributionCondition() == 0){
            //无条件
            row = examineDao.insert(examineVo);
        } else if (conf.getConfDistributionCondition() == 1) {
            //消费次数
            if(examineVo.getCostNum() >= 100)
                row = examineDao.insert(examineVo);
            else
                return 0;
        } else if (conf.getConfDistributionCondition() == 2) {
            //消费金额
            if (examineVo.getCost().compareTo(new BigDecimal(10000)) >= 0)
                row = examineDao.insert(examineVo);
            else
                return 0;
        }else {
            //购买指定商品
            List<OrderVo> orderVos = orderDao.selectList(new LambdaQueryWrapper<OrderVo>().eq(OrderVo::getUserId, examineVo.getUserId())).stream().filter(orderVo -> !"12".equals(orderVo.getOrderStatusId())).collect(Collectors.toList());
            if(orderVos == null || orderVos.size() == 0)
                return 0;
            else{
                List<Integer> goodsIds = orderVos.stream().map(OrderVo::getGoodsId).map(Integer::parseInt).collect(Collectors.toList());
                if(goodsIds.contains(1) || goodsIds.contains(2)){
                    row = examineDao.insert(examineVo);
                }else{
                    return 0;
                }
            }
        }
        return row;
    }



}
